package com.atguigu.guli.service.sms.service.impl;

import com.atguigu.guli.service.base.exception.GuliException;
import com.atguigu.guli.service.base.result.R;
import com.atguigu.guli.service.base.result.ResultCodeEnum;
import com.atguigu.guli.service.sms.entity.MemberTO;
import com.atguigu.guli.service.sms.feign.UcenterFeignClient;
import com.atguigu.guli.service.sms.service.SMSService;
import com.atguigu.guli.service.sms.util.HttpUtils;
import com.atguigu.guli.service.sms.util.SMSProperties;
import com.atguigu.guli.service.util.utils.FormUtils;
import com.atguigu.guli.service.util.utils.RandomUtils;
import com.google.gson.Gson;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class SMSServiceImpl implements SMSService {
    @Autowired
    SMSProperties smsProperties;
    @Autowired
    RedisTemplate redisTemplate;
    @Resource
    UcenterFeignClient ucenterFeignClient;
    String fourBitRandom = RandomUtils.getFourBitRandom();//随机生成四位的验证码


    @Override
    public void sendMsg(String mobile) {
        //一分钟发送验证码限制次数
        String codeForLimtKeyPermin = "sms:limit:min" + mobile;
        //一天发送验证码的限制次数key
        String codeForLimitKeyPerday = "sms:limit:day" + mobile;
        //一天发送验证码的限制次数value
        int count = 1;
        //1、验证手机格式
        boolean isMobile = FormUtils.isMobile(mobile);
        if (!isMobile){
            throw new GuliException(ResultCodeEnum.LOGIN_PHONE_ERROR);
        }
        //2、手机号是否已经注册
        //查询用户表中该手机号是否已经注册
        R r = ucenterFeignClient.isRegist(mobile);
        if (!r.getSuccess()){
            throw new GuliException(ResultCodeEnum.UNKNOWN_REASON);
        }
        String jsonitem = r.getData().get("item").toString();


        if ("1".equals(jsonitem)){
            throw  new GuliException(ResultCodeEnum.REGISTER_MOBLE_ERROR);
        }
        //4、手机号同一分钟内多次获取验证码
        if (redisTemplate.hasKey(codeForLimtKeyPermin)){
            throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL);
        }

        //3、手机号同一天是否获取多次验证码
        Object codeForLimitKeyPerdayObject = redisTemplate.opsForValue().get(codeForLimitKeyPerday);
        if (codeForLimitKeyPerdayObject!=null){
          count =  Integer.parseInt(codeForLimitKeyPerdayObject.toString());
          if (count>=3){
              throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR_BUSINESS_PERDAY_LIMIT_CONTROL);
          }else {
        //设置手机号发送验证码的次数+1
//        proxySendMsg(mobile);
              redisTemplate.opsForValue().set(codeForLimitKeyPerday,count+1,1,TimeUnit.DAYS);
          }
        }else {
            //该手机号一天内没有发送过验证码，
//            proxySendMsg(mobile);
            redisTemplate.opsForValue().set(codeForLimitKeyPerday,count,1,TimeUnit.DAYS);
        }
        //5、 以上条件均不满足才发送验证码
        //6、 发送成功，验证码和手机号缓存至redis
        String code = "sms:code" + mobile;
        redisTemplate.opsForValue().set(code, fourBitRandom, 10, TimeUnit.MINUTES);
        //初始化设置一分钟的验证码缓存,以及一天的次数缓存，仅针对于本天的第一次缓存
        redisTemplate.opsForValue().set(codeForLimtKeyPermin, "oneMinutes", 1, TimeUnit.MINUTES);
    }

    //实际使用鼎信第三方发送验证码的方法
    public void proxySendMsg(String mobile) {
        String host = smsProperties.getHost();
        String path = smsProperties.getPath();
        String method = smsProperties.getMethod();
        String appcode = smsProperties.getAppCode();
        String tpl_id = smsProperties.getTpl_id();
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", mobile);
        querys.put("param", "code:"+fourBitRandom);
        querys.put("tpl_id", tpl_id);
        Map<String, String> bodys = new HashMap<String, String>();

        try {
            HttpResponse response = (HttpResponse) HttpUtils.doPost(host, path, method, headers, querys, bodys);
            String responseJson = EntityUtils.toString(response.getEntity(), "UTF-8");
            System.out.println("responseJson = " + responseJson);

            Gson gson = new Gson();
            Map map = gson.fromJson(responseJson, Map.class);
            if (Objects.isNull(map)||!"00000".equals(map.get("return_code"))) {
                throw new RuntimeException(map.get("return_code").toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
